using System;
using System.Collections.Generic;
using System.Text;
using GAS.Common.DataSets;
using System.Management;
using System.IO;
using System.Configuration;
using System.Data;
using GAS.Common.Constants;

namespace GAS.Extractors.Win32
{
	public class Win32Extractor
	{
		enum PrinterState : int
		{
			Other = 1,
			Unknown,
			Idle,
			Printing,
			Warmup,
			Stopped_Printing,
			Offline,
			Paused,
			Error,
			Busy,
			Not_Available,
			Waiting,
			Processing,
			Initialization,
			Power_Save,
			Pending_Deletion,
			I_O_Active,
			Manual_Feed
		}

		enum ProductInstallState : int
		{
			Bad_Configuration = -6,
			Invalid_Argument = -2,
			Unknown_Package = -1,
			Advertised = 1,
			Absent = 2,
			Installed = 5
		}

		public void Extract()
		{
			string auditGuid;
			string[] auditOptionsArray;
			List<string> auditOptions;
			AuditDataSet auditDS;
			bool noWebService;

			noWebService = bool.Parse(ConfigurationManager.AppSettings["NoWebService"]);

			if (noWebService)
			{
				string[] splittedAuditOptions;

				auditOptions = new List<string>();
				splittedAuditOptions = ConfigurationManager.AppSettings["AuditOptions"].Split(',');
				foreach (string splittedAuditOption in splittedAuditOptions)
				{
					auditOptions.Add(splittedAuditOption.Trim());
				}

				Console.Write("Generating audit with auditOptions: ");
				int i = 0;
				foreach (string auditOption in auditOptions)
				{
					Console.Write(auditOption);
					if (i < auditOptions.Count - 1)
						Console.Write(", ");
				}
				Console.WriteLine();

				auditDS = GenerateAuditDataSet(auditOptions);

				Console.WriteLine("Audit DataSet generated");

				WriteXmlFile(auditDS);
			}
			else
			{
				GASWebServices.GASWebService webService;
				webService = new GASWebServices.GASWebService();

				int timeout = 300000;
				try
				{
					timeout = int.Parse(ConfigurationManager.AppSettings["webServiceTimeout"]);
				}
				catch
				{
				}
				webService.Timeout = timeout;


				Console.WriteLine("Web service generated with URL: " + webService.Url);

				auditGuid = webService.GetLastAuditCode();

				Console.WriteLine("Audit Code: " + auditGuid);

				auditOptionsArray = webService.GetAuditOptions(auditGuid);
				auditOptions = new List<string>(auditOptionsArray);

				Console.Write("Generating audit with auditOptions: ");
				int i = 0;
				foreach (string auditOption in auditOptions)
				{
					Console.Write(auditOption);
					if (i < auditOptions.Count - 1)
						Console.Write(", ");
					i++;
				}
				Console.WriteLine();

				auditDS = GenerateAuditDataSet(auditOptions);

				Console.WriteLine("Audit DataSet generated");
				
				bool dump = false;
				try
				{
					dump = bool.Parse(ConfigurationManager.AppSettings["dump"]);
				}
				catch
				{
				}

				if (dump)
					auditDS.WriteXml("dump.xml", XmlWriteMode.IgnoreSchema);

				try
				{
					webService.SaveHostAudit(auditDS, auditGuid);

					Console.WriteLine("Audit DataSet sent to web service");
				}
				catch (Exception ex)
				{
					Console.WriteLine("Exception while saving audit: " + ex.Message);
				}
			}
		}

		private void WriteXmlFile(AuditDataSet auditDS)
		{
			string fileName;
			DateTime now = DateTime.Now;
			int i;

			fileName = "audit_" + now.Year.ToString() + "." + now.Month.ToString() + "." + now.Day.ToString() + "_";

			i = 0;
			fileName = fileName + "0";
			while (File.Exists(fileName + ".xml"))
			{
				i++;
				fileName = fileName.Substring(0, fileName.LastIndexOf("_") + 1) + i;
			}
			auditDS.WriteXml(fileName + ".xml", XmlWriteMode.IgnoreSchema);
		}

		private AuditDataSet GenerateAuditDataSet(List<string> auditOptions)
		{
			List<string> wmiKeys;

			AuditDataSet auditDS;
			AuditDataSet.GAS_GROUPSRow groupsRow;
			AuditDataSet.GAS_HW_DEVICESRow hwDevicesRow;
			AuditDataSet.GAS_LOGSRow logsRow;
			AuditDataSet.GAS_NET_ADAPTERSRow netAdaptersRow;
			AuditDataSet.GAS_SOFTWARE_APPSRow softwareAppsRow;
			AuditDataSet.GAS_USER_GROUPSRow userGroupsRow;
			AuditDataSet.GAS_USERSRow userRow;
			AuditDataSet.GAS_SECURITY_SETTINGSRow securitySettingsRow;
			AuditDataSet.GAS_SO_UPDATESRow soUpdateRow;
			AuditDataSet.GAS_PROCESSESRow processRow;

			ManagementObjectSearcher oSearcher;
			ManagementObjectCollection oReturnCollection;
			DateTime nowDate;


			auditDS = new AuditDataSet();
			nowDate = DateTime.Now;

			#region Convert audit options to WMI keys

			wmiKeys = new List<string>();
			foreach (string auditOption in auditOptions)
			{
				switch (auditOption)
				{
					case GASConstants.GAS_AUDIT_OPTION_USERS_AND_GROUPS:
						wmiKeys.Add("Win32_UserAccount");
						wmiKeys.Add("Win32_Group");
						wmiKeys.Add("Win32_GroupUser");
						break;
					case GASConstants.GAS_AUDIT_OPTION_SECURITY_SETTINGS:
//						wmiKeys.Add("Win32_SecuritySetting");
						break;
					case GASConstants.GAS_AUDIT_OPTION_OPEN_PORTS:
						break;
					case GASConstants.GAS_AUDIT_OPTION_NETWORK_ADAPTERS:
						wmiKeys.Add("Win32_NetworkAdapterConfiguration");
						break;
					case GASConstants.GAS_AUDIT_OPTION_UPDATES:
						wmiKeys.Add("Win32_QuickFixEngineering");
						break;
					case GASConstants.GAS_AUDIT_OPTION_LOGS:
						wmiKeys.Add("Win32_NTLogEvent");
						break;
					case GASConstants.GAS_AUDIT_OPTION_HARDWARE:
						wmiKeys.Add("Win32_BIOS");
						wmiKeys.Add("Win32_Bus");
						wmiKeys.Add("Win32_CacheMemory");
						wmiKeys.Add("Win32_DiskDrive");
						wmiKeys.Add("Win32_DiskPartition");
						wmiKeys.Add("Win32_LogicalDisk");
						wmiKeys.Add("Win32_PhysicalMemory");
						wmiKeys.Add("Win32_Processor");
						wmiKeys.Add("Win32_VideoController");
						wmiKeys.Add("Win32_CDROMDrive");
						wmiKeys.Add("Win32_Keyboard");
						wmiKeys.Add("Win32_Printer");
						wmiKeys.Add("Win32_SoundDevice");
						wmiKeys.Add("Win32_USBHub");
						break;
					case GASConstants.GAS_AUDIT_OPTION_SOFTWARE:
						wmiKeys.Add("Win32_Product");
						break;
					case GASConstants.GAS_AUDIT_OPTION_PROCESSES:
						wmiKeys.Add("Win32_Process");
						break;
					default:
						break;
				}
			}

			#endregion

			#region Create HOST_AUDIT row

			AuditDataSet.GAS_HOST_AUDITRow hostAudit;

			hostAudit = auditDS.GAS_HOST_AUDIT.NewGAS_HOST_AUDITRow();
			hostAudit.AUDIT_ID = -1; //The web service changes it later
			hostAudit.HOST_ID = System.Net.Dns.GetHostName();
			hostAudit.AUDIT_DATETIME = nowDate;
			auditDS.GAS_HOST_AUDIT.AddGAS_HOST_AUDITRow(hostAudit);

			#endregion

			#region Process WMI Keys

			foreach (string wmiKey in wmiKeys)
			{
				Console.WriteLine("WMI Select: select * from " + wmiKey);

				//Execute the query 
				oSearcher = new ManagementObjectSearcher("select * from " + wmiKey);

				//Get the results
				oReturnCollection = oSearcher.Get();

				//loop through found drives and write out info
				foreach (ManagementObject oReturn in oReturnCollection)
				{
					if (wmiKey == "Win32_UserAccount")
					{
						Console.WriteLine("Before generating Win32_UserAccount");
						#region Win32_UserAccount
						userRow = auditDS.GAS_USERS.NewGAS_USERSRow();


						userRow.USER_CODE = oReturn["Name"].ToString();

						userRow.FULL_NAME = oReturn["FullName"].ToString();
						userRow.COMMENTS = oReturn["Description"].ToString();

						if (oReturn["PasswordExpires"].ToString().Equals("True"))
							userRow.PASSWORD_EXPIRED = 1;
						else
							userRow.PASSWORD_EXPIRED = 0;
						if (oReturn["Disabled"].ToString().Equals("True"))
							userRow.ACCOUNT_EXPIRES = 1;
						else
							userRow.ACCOUNT_EXPIRES = 0;

						userRow.HOST_AUDIT = hostAudit.ID;

						string cadena = "Disabled: " + oReturn["Disabled"].ToString() + "; "
							+ "Lockout: " + oReturn["Disabled"].ToString() + "; "
							+ "Status: " + oReturn["Status"].ToString();

						userRow.ACCOUNT_STATUS = cadena;

						auditDS.GAS_USERS.AddGAS_USERSRow(userRow);

						#endregion
						Console.WriteLine("After generating Win32_UserAccount");
					}
					else if (wmiKey == "Win32_Group")
					{
						Console.WriteLine("Before generating Win32_Group");
						#region Win32_Group
						groupsRow = auditDS.GAS_GROUPS.NewGAS_GROUPSRow();

						groupsRow.GROUP_NAME = oReturn["Name"].ToString();

						groupsRow.GROUP_TYPE = oReturn["LocalAccount"].ToString();

						groupsRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_GROUPS.AddGAS_GROUPSRow(groupsRow);
						#endregion
						Console.WriteLine("After generating Win32_Group");
					}
					else if (wmiKey == "Win32_GroupUser")
					{
						Console.WriteLine("Before generating Win32_GroupUser");
						#region Win32_GroupUser
						// User
						string user = oReturn["PartComponent"].ToString();
						user = user.Substring(user.LastIndexOf("=") + 2, user.LastIndexOf("\"") - user.LastIndexOf("=") - 2);
						// Group
						string group = oReturn["GroupComponent"].ToString();
						group = group.Substring(group.LastIndexOf("=") + 2, group.LastIndexOf("\"") - group.LastIndexOf("=") - 2);

						AuditDataSet.GAS_GROUPSRow[] groups = (AuditDataSet.GAS_GROUPSRow[])auditDS.GAS_GROUPS.Select("GROUP_NAME = '" + group + "'");
						AuditDataSet.GAS_USERSRow[] users = (AuditDataSet.GAS_USERSRow[])auditDS.GAS_USERS.Select("USER_CODE = '" + user + "'");
						if (groups.Length == 1 && users.Length == 1)
						{
							userGroupsRow = auditDS.GAS_USER_GROUPS.NewGAS_USER_GROUPSRow();

							userGroupsRow.GAS_USER = users[0].ID;
							userGroupsRow.GAS_GROUP = groups[0].ID;

							auditDS.GAS_USER_GROUPS.AddGAS_USER_GROUPSRow(userGroupsRow);
						}
						#endregion
						Console.WriteLine("After generating Win32_GroupUser");
					}
					else if (wmiKey == "Win32_NetworkAdapterConfiguration")
					{
						Console.WriteLine("Before generating Win32_NetworkAdapterConfiguration");
						#region Win32_NetworkAdapterConfiguration
						netAdaptersRow = auditDS.GAS_NET_ADAPTERS.NewGAS_NET_ADAPTERSRow();

						netAdaptersRow.ADAPTER_NAME = oReturn["Caption"].ToString().Substring(oReturn["Caption"].ToString().IndexOf("]") + 2, oReturn["Caption"].ToString().Length - oReturn["Caption"].ToString().IndexOf("]") - 2);

						if (oReturn["IPAddress"] != null)
							if (oReturn["IPAddress"].ToString().StartsWith("System"))
								netAdaptersRow.IP_ADDRESS = "0.0.0.0";
							else
								netAdaptersRow.IP_ADDRESS = oReturn["IPAddress"].ToString();

						if ((oReturn["IPSubnet"] != null) && (!(oReturn["IPSubnet"].ToString().StartsWith("System"))))
							netAdaptersRow.SUBNET_MASK = oReturn["IPSubnet"].ToString();
						if ((oReturn["DefaultIPGateway"] != null) && (!(oReturn["DefaultIPGateway"].ToString().StartsWith("System"))))
							netAdaptersRow.DEFAULT_GW = oReturn["DefaultIPGateway"].ToString();
						if ((oReturn["MacAddress"] != null) && (!(oReturn["MacAddress"].ToString().StartsWith("System"))))
							netAdaptersRow.MAC_ADDRESS = oReturn["MacAddress"].ToString();

						if (oReturn["DHCPEnabled"].ToString().Equals("True"))
							netAdaptersRow.DHCP_ENABLED = 1;
						else
							netAdaptersRow.DHCP_ENABLED = 0;

						netAdaptersRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_NET_ADAPTERS.AddGAS_NET_ADAPTERSRow(netAdaptersRow);
						#endregion
						Console.WriteLine("After generating Win32_NetworkAdapterConfiguration");
					}
					else if (wmiKey == "Win32_BIOS")
					{
						Console.WriteLine("Before generating Win32_BIOS");
						#region Win32_BIOS
						hwDevicesRow = auditDS.GAS_HW_DEVICES.NewGAS_HW_DEVICESRow();

						hwDevicesRow.DEVICE_NAME = oReturn["Caption"].ToString();
						hwDevicesRow.MANUFACTURER = oReturn["Manufacturer"].ToString();
						hwDevicesRow.VERSION = oReturn["Version"].ToString();

						// Description
						String aux1 = "";
						if (oReturn["SerialNumber"] != null)
							aux1 = oReturn["SerialNumber"].ToString();
						String aux2 = "";
						if (oReturn["CodeSet"] != null)
							aux2 = oReturn["CodeSet"].ToString();
						String aux3 = "";
						if (oReturn["ReleaseDate"] != null)
						{
							aux3 = oReturn["ReleaseDate"].ToString();
							int year = int.Parse(aux3.Substring(0, 4));
							int month = int.Parse(aux3.Substring(4, 2));
							int day = int.Parse(aux3.Substring(6, 2));
							int hour = int.Parse(aux3.Substring(8, 2));
							int min = int.Parse(aux3.Substring(10, 2));
							int seg = int.Parse(aux3.Substring(12, 2));

							DateTime dateAux = new DateTime(year, month, day, hour, min, seg);
							aux3 = dateAux.ToString();
						}

						hwDevicesRow.DESCRIPTION = "\n\t\t\tSerial Number: " + aux1 + ";" +
							"\n\t\t\tIdentification Number: " + aux2 + ";" +
							"\n\t\t\tRelease Date: " + aux3 + ";\n\t";

						hwDevicesRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_HW_DEVICES.AddGAS_HW_DEVICESRow(hwDevicesRow);
						#endregion
						Console.WriteLine("After generating Win32_BIOS");
					}
					else if (wmiKey == "Win32_Bus")
					{
						Console.WriteLine("Before generating Win32_Bus");
						#region Win32_Bus
						hwDevicesRow = auditDS.GAS_HW_DEVICES.NewGAS_HW_DEVICESRow();

						hwDevicesRow.DEVICE_NAME = oReturn["DeviceID"].ToString();

						// Description
						String aux1 = "";
						if (oReturn["BusNum"] != null)
							aux1 = oReturn["BusNum"].ToString();
						String aux2 = "";
						if (oReturn["BusType"] != null)
							aux2 = oReturn["BusType"].ToString();

						hwDevicesRow.DESCRIPTION = "\n\t\t\tBus Number: " + aux1 + ";" +
							"\n\t\t\tBus Type: " + aux2 + ";\n\t";

						hwDevicesRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_HW_DEVICES.AddGAS_HW_DEVICESRow(hwDevicesRow);
						#endregion
						Console.WriteLine("After generating Win32_Bus");
					}
					else if (wmiKey == "Win32_CacheMemory")
					{
						Console.WriteLine("Before generating Win32_CacheMemory");
						#region Win32_CacheMemory
						hwDevicesRow = auditDS.GAS_HW_DEVICES.NewGAS_HW_DEVICESRow();

						hwDevicesRow.DEVICE_NAME = oReturn["DeviceID"].ToString();

						// Description
						String aux1 = "";
						if (oReturn["Access"] != null)
							aux1 = oReturn["Access"].ToString();

						hwDevicesRow.DESCRIPTION = "\n\t\t\tBus Access Type: " + aux1 + ";" +
							"\n\t\t\tCache Type: " + oReturn["CacheType"].ToString() + ";" +
							"\n\t\t\tLevel Cache: " + oReturn["Level"].ToString() + ";" +
							"\n\t\t\tCache Type: " + oReturn["CacheType"].ToString() + ";" +
							"\n\t\t\tBlock Size: " + oReturn["BlockSize"].ToString() + " bytes;" +
							"\n\t\t\tNumber of Blocks: " + oReturn["NumberOfBlocks"].ToString() + ";" +
							"\n\t";

						hwDevicesRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_HW_DEVICES.AddGAS_HW_DEVICESRow(hwDevicesRow);
						#endregion
						Console.WriteLine("After generating Win32_CacheMemory");
					}
					else if (wmiKey == "Win32_DiskDrive")
					{
						Console.WriteLine("Before generating Win32_DiskDrive");
						#region Win32_DiskDrive
						hwDevicesRow = auditDS.GAS_HW_DEVICES.NewGAS_HW_DEVICESRow();

						hwDevicesRow.DEVICE_NAME = oReturn["Caption"].ToString();
						hwDevicesRow.MANUFACTURER = oReturn["Manufacturer"].ToString();

						// Description
						String aux1 = "";
						if (oReturn["Model"] != null)
							aux1 = oReturn["Model"].ToString();
						String aux2 = "";
						if (oReturn["DeviceId"] != null)
							aux2 = oReturn["DeviceId"].ToString();
						String aux3 = "";
						if (oReturn["InterfaceType"] != null)
							aux3 = oReturn["InterfaceType"].ToString();
						String aux4 = "";
						if (oReturn["MediaType"] != null)
							aux4 = oReturn["MediaType"].ToString();
						String aux5 = "";
						if (oReturn["BytesperSector"] != null)
							aux5 = oReturn["BytesperSector"].ToString();
						String aux6 = "";
						if (oReturn["Partitions"] != null)
							aux6 = oReturn["Partitions"].ToString();
						String aux7 = "";
						if (oReturn["TotalCylinders"] != null)
							aux7 = oReturn["TotalCylinders"].ToString();
						String aux8 = "";
						if (oReturn["TotalHeads"] != null)
							aux8 = oReturn["TotalHeads"].ToString();
						String aux9 = "";
						if (oReturn["TotalSectors"] != null)
							aux9 = oReturn["TotalSectors"].ToString();
						String aux10 = "";
						if (oReturn["TotalTracks"] != null)
							aux10 = oReturn["TotalTracks"].ToString();

						hwDevicesRow.DESCRIPTION = "\n\t\t\tModel: " + aux1 + ";" +
							"\n\t\t\tID Name: " + aux2 + ";" +
							"\n\t\t\tInterface Type: " + aux3 + ";" +
							"\n\t\t\tMedia Type: " + aux4 + ";" +
							"\n\t\t\tBytes per Sector: " + aux5 + ";" +
							"\n\t\t\tPartitions: " + aux6 + ";" +
							"\n\t\t\tTotal Cylindres: " + aux7 + ";" +
							"\n\t\t\tTotal Heads: " + aux8 + ";" +
							"\n\t\t\tTotal Sectors: " + aux9 + ";" +
							"\n\t\t\tTotal Tracks: " + aux10 + ";" +
							"\n\t";

						hwDevicesRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_HW_DEVICES.AddGAS_HW_DEVICESRow(hwDevicesRow);
						#endregion
						Console.WriteLine("After generating Win32_DiskDrive");
					}
					else if (wmiKey == "Win32_DiskPartition")
					{
						Console.WriteLine("Before generating Win32_DiskPartition");
						#region Win32_DiskPartition
						hwDevicesRow = auditDS.GAS_HW_DEVICES.NewGAS_HW_DEVICESRow();

						hwDevicesRow.DEVICE_NAME = oReturn["DeviceId"].ToString();

						// Description
						String aux1 = "";
						if (oReturn["BlockSize"] != null)
							aux1 = oReturn["BlockSize"].ToString() + " bytes";
						String aux2 = "";
						if (oReturn["NumberOfBlocks"] != null)
							aux2 = oReturn["NumberOfBlocks"].ToString();
						String aux3 = "";
						if (oReturn["Size"] != null)
							aux3 = oReturn["Size"].ToString() + " bytes";
						String aux4 = "";
						if (oReturn["StartingOffset"] != null)
							aux4 = oReturn["StartingOffset"].ToString() + " bytes";
						String aux5 = "";
						if (oReturn["BootPartition"] != null)
							aux5 = oReturn["BootPartition"].ToString();
						String aux6 = "";
						if (oReturn["Description"] != null)
							aux6 = oReturn["Description"].ToString();
						String aux7 = "";
						if (oReturn["DiskIndex"] != null)
							aux7 = oReturn["DiskIndex"].ToString();

						hwDevicesRow.DESCRIPTION = "\n\t\t\tBlock Size: " + aux1 + ";" +
							"\n\t\t\tNumber of Blocks: " + aux2 + ";" +
							"\n\t\t\tSize: " + aux3 + ";" +
							"\n\t\t\tStarting Offset: " + aux4 + ";" +
							"\n\t\t\tBoot Partition: " + aux5 + ";" +
							"\n\t\t\tType: " + aux6 + ";" +
							"\n\t\t\tDisk Index: " + aux7 + ";" +
							"\n\t";

						hwDevicesRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_HW_DEVICES.AddGAS_HW_DEVICESRow(hwDevicesRow);
						#endregion
						Console.WriteLine("After generating Win32_DiskPartition");
					}
					else if (wmiKey == "Win32_LogicalDisk")
					{
						Console.WriteLine("Before generating Win32_LogicalDisk");
						#region Win32_LogicalDisk
						hwDevicesRow = auditDS.GAS_HW_DEVICES.NewGAS_HW_DEVICESRow();

						hwDevicesRow.DEVICE_NAME = oReturn["Caption"].ToString();

						// Description
						String aux1 = "";
						if (oReturn["FileSystem"] != null)
							aux1 = oReturn["FileSystem"].ToString();
						String aux2 = "";
						if (oReturn["Size"] != null)
							aux2 = oReturn["Size"].ToString() + " bytes";
						String aux3 = "";
						if (oReturn["FreeSpace"] != null)
							aux3 = oReturn["FreeSpace"].ToString() + " bytes";
						String aux4 = "";
						if (oReturn["DriveType"] != null)
							aux4 = oReturn["DriveType"].ToString();
						String aux5 = "";
						if (oReturn["VolumeName"] != null)
							aux5 = oReturn["VolumeName"].ToString();
						String aux6 = "";
						if (oReturn["VolumeDirty"] != null)
							aux6 = oReturn["VolumeDirty"].ToString();
						String aux7 = "";
						if (oReturn["VolumeSerialNumber"] != null)
							aux7 = oReturn["VolumeSerialNumber"].ToString();
						String aux8 = "";
						if (oReturn["Compressed"] != null)
							aux8 = oReturn["Compressed"].ToString();
						String aux9 = "";
						if (oReturn["QuotasDisabled"] != null)
							aux9 = oReturn["QuotasDisabled"].ToString();

						hwDevicesRow.DESCRIPTION = "\n\t\t\tFileSystem: " + aux1 + ";" +
							"\n\t\t\tSize: " + aux2 + ";" +
							"\n\t\t\tFreeSpace: " + aux3 + ";" +
							"\n\t\t\tDrive Type: " + aux4 + ";" +
							"\n\t\t\tVolume Name: " + aux5 + ";" +
							"\n\t\t\tVolume Dirty: " + aux6 + ";" +
							"\n\t\t\tVolume Serial Number: " + aux7 + ";" +
							"\n\t\t\tCompressed: " + aux8 + ";" +
							"\n\t\t\tQuotas Disabled: " + aux9 + ";" +
							"\n\t";

						hwDevicesRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_HW_DEVICES.AddGAS_HW_DEVICESRow(hwDevicesRow);
						#endregion
						Console.WriteLine("After generating Win32_LogicalDisk");
					}
					else if (wmiKey == "Win32_CDROMDrive")
					{
						Console.WriteLine("Before generating Win32_CDROMDrive");
						#region Win32_CDROMDrive
						hwDevicesRow = auditDS.GAS_HW_DEVICES.NewGAS_HW_DEVICESRow();

						hwDevicesRow.DEVICE_NAME = oReturn["Caption"].ToString();
						hwDevicesRow.MANUFACTURER = oReturn["Manufacturer"].ToString();

						// Description
						String aux1 = "";
						if (oReturn["Description"] != null)
							aux1 = oReturn["Description"].ToString();
						String aux2 = "";
						if (oReturn["Drive"] != null)
							aux2 = oReturn["Drive"].ToString();
						String aux3 = "";
						if (oReturn["Status"] != null)
							aux3 = oReturn["Status"].ToString();

						hwDevicesRow.DESCRIPTION = "\n\t\t\tDescription: " + aux1 + ";" +
							"\n\t\t\tDrive: " + aux2 + ";" +
							"\n\t\t\tStatus: " + aux3 + ";" +
							"\n\t";

						hwDevicesRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_HW_DEVICES.AddGAS_HW_DEVICESRow(hwDevicesRow);
						#endregion
						Console.WriteLine("After generating Win32_CDROMDrive");
					}
					else if (wmiKey == "Win32_Keyboard")
					{
						Console.WriteLine("Before generating Win32_Keyboard");
						#region Win32_Keyboard
						hwDevicesRow = auditDS.GAS_HW_DEVICES.NewGAS_HW_DEVICESRow();

						hwDevicesRow.DEVICE_NAME = oReturn["DeviceID"].ToString();

						// Description
						String aux1 = "";
						if (oReturn["Description"] != null)
							aux1 = oReturn["Description"].ToString();
						String aux2 = "";
						if (oReturn["NumberOfFunctionKeys"] != null)
							aux2 = oReturn["NumberOfFunctionKeys"].ToString() + " bytes";
						String aux3 = "";
						if (oReturn["Status"] != null)
							aux3 = oReturn["Status"].ToString() + " bytes";

						hwDevicesRow.DESCRIPTION = "\n\t\t\tDescription: " + aux1 + ";" +
							"\n\t\t\tNumber of Function Keys: " + aux2 + ";" +
							"\n\t\t\tStatus: " + aux3 + ";" +
							 "\n\t";

						hwDevicesRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_HW_DEVICES.AddGAS_HW_DEVICESRow(hwDevicesRow);
						#endregion
						Console.WriteLine("After generating Win32_Keyboard");
					}
					else if (wmiKey == "Win32_Printer")
					{
						Console.WriteLine("Before generating Win32_Printer");
						#region Win32_Printer
						hwDevicesRow = auditDS.GAS_HW_DEVICES.NewGAS_HW_DEVICESRow();

						hwDevicesRow.DEVICE_NAME = oReturn["Caption"].ToString();

						// Description
						String aux1 = "";
						if (oReturn["Default"] != null)
							aux1 = oReturn["Default"].ToString();
						String aux2 = "";
						if (oReturn["Local"] != null)
							aux2 = oReturn["Local"].ToString();
						String aux3 = "";
						if (oReturn["PortName"] != null)
							aux3 = oReturn["PortName"].ToString();
						String aux4 = "";
						if (oReturn["PrinterStatus"] != null)
							aux4 = Enum.GetName(typeof(PrinterState), int.Parse(oReturn["PrinterStatus"].ToString()));
						String aux5 = "";
						if (oReturn["SpoolEnabled"] != null)
							aux5 = oReturn["SpoolEnabled"].ToString();
						String aux6 = "";
						if (oReturn["Shared"] != null)
							aux6 = oReturn["Shared"].ToString();

						hwDevicesRow.DESCRIPTION = "\n\t\t\tDefault Printer: " + aux1 + ";" +
							"\n\t\t\tLocal: " + aux2 + ";" +
							"\n\t\t\tPort Name: " + aux3 + ";" +
							"\n\t\t\tPrinter Status: " + aux4 + ";" +
							"\n\t\t\tSpool Enabled: " + aux5 + ";" +
							"\n\t\t\tShared: " + aux6 + ";" +
							 "\n\t";

						hwDevicesRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_HW_DEVICES.AddGAS_HW_DEVICESRow(hwDevicesRow);
						#endregion
						Console.WriteLine("After generating Win32_Printer");
					}
					else if (wmiKey == "Win32_SoundDevice")
					{
						Console.WriteLine("Before generating Win32_SoundDevice");
						#region Win32_soundDevice
						hwDevicesRow = auditDS.GAS_HW_DEVICES.NewGAS_HW_DEVICESRow();

						hwDevicesRow.DEVICE_NAME = oReturn["Caption"].ToString();
						hwDevicesRow.MANUFACTURER = oReturn["Manufacturer"].ToString();

						// Description
						String aux1 = "";
						if (oReturn["Status"] != null)
							aux1 = oReturn["Status"].ToString();

						hwDevicesRow.DESCRIPTION = "\n\t\t\tStatus: " + aux1 + ";" +
							"\n\t";

						hwDevicesRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_HW_DEVICES.AddGAS_HW_DEVICESRow(hwDevicesRow);
						#endregion
						Console.WriteLine("After generating Win32_SoundDevice");
					}
					else if (wmiKey == "Win32_USBHub")
					{
						Console.WriteLine("Before generating Win32_USBHub");
						#region Win32_USBHub
						hwDevicesRow = auditDS.GAS_HW_DEVICES.NewGAS_HW_DEVICESRow();

						hwDevicesRow.DEVICE_NAME = oReturn["Name"].ToString();

						// Description
						String aux1 = "";
						if (oReturn["DeviceId"] != null)
							aux1 = oReturn["DeviceId"].ToString();
						String aux2 = "";
						if (oReturn["Description"] != null)
							aux2 = oReturn["Description"].ToString();
						String aux3 = "";
						if (oReturn["Status"] != null)
							aux3 = oReturn["Status"].ToString();

						hwDevicesRow.DESCRIPTION = "\n\t\t\tDeviceID: " + aux1 + ";" +
							"\n\t\t\tDescription: " + aux2 + ";" +
							"\n\t\t\tStatus: " + aux3 + ";" +
							"\n\t";

						hwDevicesRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_HW_DEVICES.AddGAS_HW_DEVICESRow(hwDevicesRow);
						#endregion
						Console.WriteLine("After generating Win32_USBHub");
					}
					else if (wmiKey == "Win32_PhysicalMemory")
					{
						Console.WriteLine("Before generating Win32_PhysicalMemory");
						#region Win32_PhysicalMemory
						hwDevicesRow = auditDS.GAS_HW_DEVICES.NewGAS_HW_DEVICESRow();

						hwDevicesRow.DEVICE_NAME = oReturn["Tag"].ToString();

						// Description
						String aux1 = "";
						if (oReturn["Capacity"] != null)
							aux1 = oReturn["Capacity"].ToString();
						String aux2 = "";
						if (oReturn["DataWidth"] != null)
							aux2 = oReturn["DataWidth"].ToString();
						String aux3 = "";
						if (oReturn["TotalWidth"] != null)
							aux3 = oReturn["TotalWidth"].ToString();
						String aux4 = "";
						if (oReturn["MemoryType"] != null)
							aux4 = oReturn["MemoryType"].ToString();
						String aux5 = "";
						if (oReturn["Speed"] != null)
							aux5 = oReturn["Speed"].ToString();

						hwDevicesRow.DESCRIPTION = "\n\t\t\tCapacity: " + aux1 + ";" +
							"\n\t\t\tData Width: " + aux2 + ";" +
							"\n\t\t\tTotal Width: " + aux3 + ";" +
							"\n\t\t\tMemory Type: " + aux4 + ";" +
							"\n\t\t\tSpeed: " + aux5 + ";" +
							"\n\t";

						hwDevicesRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_HW_DEVICES.AddGAS_HW_DEVICESRow(hwDevicesRow);
						#endregion
						Console.WriteLine("After generating Win32_PhysicalMemory");
					}
					else if (wmiKey == "Win32_Processor")
					{
						Console.WriteLine("Before generating Win32_Processor");
						#region Win32_Processor
						hwDevicesRow = auditDS.GAS_HW_DEVICES.NewGAS_HW_DEVICESRow();

						hwDevicesRow.DEVICE_NAME = oReturn["Name"].ToString().TrimStart();
						hwDevicesRow.MANUFACTURER = oReturn["Manufacturer"].ToString();
						hwDevicesRow.VERSION = oReturn["Version"].ToString();

						// Description
						String aux0 = "";
						if (oReturn["Description"] != null)
							aux0 = oReturn["Description"].ToString();
						String aux1 = "";
						if (oReturn["DeviceID"] != null)
							aux1 = oReturn["DeviceID"].ToString();
						String aux2 = "";
						if (oReturn["Architecture"] != null)
							aux2 = oReturn["Architecture"].ToString();
						String aux3 = "";
						if (oReturn["DataWidth"] != null)
							aux3 = oReturn["DataWidth"].ToString();
						String aux4 = "";
						if (oReturn["AddressWidth"] != null)
							aux4 = oReturn["AddressWidth"].ToString();
						String aux5 = "";
						if (oReturn["CurrentClockSpeed"] != null)
							aux5 = oReturn["CurrentClockSpeed"].ToString();
						String aux6 = "";
						if (oReturn["MaxClockSpeed"] != null)
							aux6 = oReturn["MaxClockSpeed"].ToString();
						String aux7 = "";
						if (oReturn["CurrentVoltage"] != null)
							aux7 = oReturn["CurrentVoltage"].ToString();
						String aux8 = "";
						if (oReturn["L2CacheSize"] != null)
							aux8 = oReturn["L2CacheSize"].ToString();
						String aux9 = "";
						if (oReturn["Role"] != null)
							aux9 = oReturn["Role"].ToString();
						String aux10 = "";
						if (oReturn["Status"] != null)
							aux10 = oReturn["Status"].ToString();

						hwDevicesRow.DESCRIPTION =
							"\n\t\t\tFamily: " + aux0 + ";" +
							"\n\t\t\tDevice ID: " + aux1 + ";" +
							"\n\t\t\tArchitecture: " + aux2 + ";" +
							"\n\t\t\tData Width: " + aux3 + ";" +
							"\n\t\t\tAddress Width: " + aux4 + ";" +
							"\n\t\t\tCurrent Clock Speed: " + aux5 + ";" +
							"\n\t\t\tMax Clock Speed: " + aux6 + ";" +
							"\n\t\t\tCurrentVoltage: " + aux7 + ";" +
							"\n\t\t\tL2 Cache Size: " + aux8 + ";" +
							"\n\t\t\tRole: " + aux9 + ";" +
							"\n\t\t\tStatus: " + aux10 + ";" +
							"\n\t";

						hwDevicesRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_HW_DEVICES.AddGAS_HW_DEVICESRow(hwDevicesRow);
						#endregion
						Console.WriteLine("After generating Win32_Processor");
					}
					else if (wmiKey == "Win32_VideoController")
					{
						Console.WriteLine("Before generating Win32_VideoController");
						#region Win32_VideoController
						hwDevicesRow = auditDS.GAS_HW_DEVICES.NewGAS_HW_DEVICESRow();

						hwDevicesRow.DEVICE_NAME = oReturn["Caption"].ToString();

						// Description
						String aux1 = "";
						if (oReturn["DeviceID"] != null)
							aux1 = oReturn["DeviceID"].ToString();
						String aux2 = "";
						if (oReturn["AdapterRam"] != null)
							aux2 = oReturn["AdapterRam"].ToString();
						String aux3 = "";
						if (oReturn["AdapterDACType"] != null)
							aux3 = oReturn["AdapterDACType"].ToString();
						String aux4 = "";
						if (oReturn["CurrentBitsPerPixel"] != null)
							aux4 = oReturn["CurrentBitsPerPixel"].ToString();
						String aux5 = "";
						if (oReturn["CurrentHorizontalResolution"] != null)
							aux5 = oReturn["CurrentHorizontalResolution"].ToString();
						String aux6 = "";
						if (oReturn["CurrentVerticalResolution"] != null)
							aux6 = oReturn["CurrentVerticalResolution"].ToString();
						String aux7 = "";
						if (oReturn["CurrentNumberOfColors"] != null)
							aux7 = oReturn["CurrentNumberOfColors"].ToString();
						String aux8 = "";
						if (oReturn["CurrentRefreshRate"] != null)
							aux8 = oReturn["CurrentRefreshRate"].ToString();
						String aux9 = "";
						if (oReturn["Status"] != null)
							aux9 = oReturn["Status"].ToString();

						hwDevicesRow.DESCRIPTION = "\n\t\t\tDevice ID: " + aux1 + ";" +
							"\n\t\t\tAdapter RAM: " + aux2 + ";" +
							"\n\t\t\tAdapter DAC Type: " + aux3 + ";" +
							"\n\t\t\tCurrent Bits Per Pixel: " + aux4 + ";" +
							"\n\t\t\tCurrent Horizontal Resolution: " + aux5 + ";" +
							"\n\t\t\tCurrent Vertical Resolution: " + aux6 + ";" +
							"\n\t\t\tCurrent Number of Colors: " + aux7 + ";" +
							"\n\t\t\tCurrent Refresh Rate: " + aux8 + ";" +
							"\n\t\t\tStatus: " + aux9 + ";" +
							"\n\t";

						hwDevicesRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_HW_DEVICES.AddGAS_HW_DEVICESRow(hwDevicesRow);
						#endregion
						Console.WriteLine("After generating Win32_VideoController");
					}
					else if (wmiKey == "Win32_Product")
					{
						Console.WriteLine("Before generating Win32_Product");
						#region Win32_Product
						softwareAppsRow = auditDS.GAS_SOFTWARE_APPS.NewGAS_SOFTWARE_APPSRow();

						softwareAppsRow.NAME = oReturn["Name"].ToString();
						softwareAppsRow.VERSION = oReturn["Version"].ToString();
						if (softwareAppsRow.VERSION.Length > 20)
							softwareAppsRow.VERSION = softwareAppsRow.VERSION.Substring(0, 20);

						// Description
						String aux1 = "";
						if (oReturn["InstallDate"] != null)
						{
							aux1 = oReturn["InstallDate"].ToString();
							int ano = int.Parse(aux1.Substring(0, 4));
							int mes = int.Parse(aux1.Substring(4, 2));
							int dia = int.Parse(aux1.Substring(6, 2));
							aux1 = new DateTime(ano, mes, dia).ToString();
						}
						String aux2 = "";
						if (oReturn["Vendor"] != null)
							aux2 = oReturn["Vendor"].ToString();
						String aux3 = "";
						if (oReturn["PackageCache"] != null)
							aux3 = oReturn["PackageCache"].ToString();
						String aux4 = "";
						if (oReturn["InstallState"] != null)
						{
							aux4 = Enum.GetName(typeof(ProductInstallState), int.Parse(oReturn["InstallState"].ToString()));
						}

						softwareAppsRow.DESCRIPTION = "\n\t\t\tInstallDate: " + aux1 + ";" +
							"\n\t\t\tVendor: " + aux2 + ";" +
							"\n\t\t\tPackage Cache: " + aux3 + ";" +
							"\n\t\t\tInstall State: " + aux4 + ";" +
							"\n\t";

						softwareAppsRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_SOFTWARE_APPS.AddGAS_SOFTWARE_APPSRow(softwareAppsRow);
						#endregion
						Console.WriteLine("After generating Win32_Product");
					}
					else if (wmiKey == "Win32_NTLogEvent")
					{
						Console.WriteLine("Before generating Win32_NTLogEvent");
						#region Win32_NTLogEvent
						logsRow = auditDS.GAS_LOGS.NewGAS_LOGSRow();

						logsRow.SOURCE = oReturn["SourceName"].ToString();

						string fecha = oReturn["TimeGenerated"].ToString();
						int ano = int.Parse(fecha.Substring(0, 4));
						int mes = int.Parse(fecha.Substring(4, 2));
						int dia = int.Parse(fecha.Substring(6, 2));
						int h = int.Parse(fecha.Substring(8, 2));
						int m = int.Parse(fecha.Substring(10, 2));
						int s = int.Parse(fecha.Substring(12, 2));
						logsRow.TIME_GENERATED = new DateTime(ano, mes, dia, h, m, s, 0);

						string aux = "";
						if (oReturn["Message"] != null)
						{
							aux = oReturn["Message"].ToString();
						}
						logsRow.DESCRIPTION = "/n/t/t" + aux + "/n/t";
						if (logsRow.DESCRIPTION.Length > 800)
							logsRow.DESCRIPTION = logsRow.DESCRIPTION.Substring(0, 800);

						logsRow.HOST_AUDIT = hostAudit.ID;

						auditDS.GAS_LOGS.AddGAS_LOGSRow(logsRow);
						#endregion
						Console.WriteLine("After generating Win32_NTLogEvent");
					}
					else if (wmiKey == "Win32_SecuritySetting")
					{
						Console.WriteLine("Before generating Win32_SecuritySetting");
						#region Win32_SecuritySetting

						//securitySettings = 


						#endregion
						Console.WriteLine("After generating Win32_SecuritySetting");
					}
					else if (wmiKey == "Win32_QuickFixEngineering")
					{
						Console.WriteLine("Before generating Win32_QuickFixEngineering");
						#region Win32_QuickFixEngineering
						soUpdateRow = auditDS.GAS_SO_UPDATES.NewGAS_SO_UPDATESRow();
						if (oReturn["Name"] != null)
							soUpdateRow.NAME = oReturn["Name"].ToString();
						else
						{
							if (oReturn["Description"].ToString().Length > 200)
								soUpdateRow.NAME = oReturn["Description"].ToString().Substring(0, 200);
							else
								soUpdateRow.NAME = oReturn["Description"].ToString();
						}
						soUpdateRow.VERSION = oReturn["HotFixID"].ToString();
						soUpdateRow.DESCRIPTION = "FixComments: " + oReturn["FixComments"].ToString() + "; InstallDate: " + ((oReturn["InstallDate"] != null) ? oReturn["InstallDate"].ToString() : "") + "; InstalledBy: " + oReturn["InstalledBy"].ToString() + "; InstalledOn: " + oReturn["InstalledOn"].ToString() + "; ServicePackInEffect: " + oReturn["ServicePackInEffect"].ToString() + "; Status: " + ((oReturn["Status"] != null) ? oReturn["Status"].ToString() : "");
						soUpdateRow.HOST_AUDIT = hostAudit.ID;
						auditDS.GAS_SO_UPDATES.AddGAS_SO_UPDATESRow(soUpdateRow);
						#endregion
						Console.WriteLine("After generating Win32_QuickFixEngineering");
					}
					else if (wmiKey == "Win32_Process")
					{
						Console.WriteLine("Before generating Win32_Process");
						#region Win32_Process
						processRow = auditDS.GAS_PROCESSES.NewGAS_PROCESSESRow();
						processRow.NAME = oReturn["ProcessId"].ToString() + "-" + oReturn["Caption"].ToString();
						processRow.MEMORY_BYTES = Convert.ToDecimal(oReturn["WorkingSetSize"]);
						try
						{
							TimeSpan execTime = DateTime.Now - Convert.ToDateTime(oReturn["CreationDate"]);
							processRow.EXEC_TIME = execTime.Milliseconds;
						}
						catch
						{
						}
						processRow.HOST_AUDIT = hostAudit.ID;
						auditDS.GAS_PROCESSES.AddGAS_PROCESSESRow(processRow);
						#endregion
						Console.WriteLine("After generating Win32_Process");
					}
				}
			}

			#endregion

			Console.WriteLine("Before generating Open ports with IPHlpApi.dll");
			#region Open ports with IPHlpApi.dll

			AuditDataSet.GAS_OPEN_PORTSRow openPortRow;
			IpHlpApidotnet.IPHelper ipHelper;

			ipHelper = new IpHlpApidotnet.IPHelper();

			// TCP
			ipHelper.GetExTcpConnexions();
			for (int i = 0; i < ipHelper.TcpExConnexions.dwNumEntries; i++)
			{
				openPortRow = auditDS.GAS_OPEN_PORTS.NewGAS_OPEN_PORTSRow();
				openPortRow.PORT_NUMBER = decimal.Parse(ipHelper.TcpExConnexions.table[i].Local.Port.ToString());
				openPortRow.PORT_TYPE = "TCP";
				openPortRow.STATE = ipHelper.TcpExConnexions.table[i].StrgState;
				openPortRow.SERVICE = ipHelper.TcpExConnexions.table[i].ProcessName;
				openPortRow.HOST_AUDIT = hostAudit.ID;
				openPortRow.MORE_DETAILS = "FROM: " + ipHelper.TcpExConnexions.table[i].Local.Address.ToString() + ":" + ipHelper.TcpExConnexions.table[i].Local.Port.ToString() + " TO: " + ipHelper.TcpExConnexions.table[i].Remote.Address.ToString() + ":" + ipHelper.TcpExConnexions.table[i].Remote.Port.ToString();
				auditDS.GAS_OPEN_PORTS.AddGAS_OPEN_PORTSRow(openPortRow);
			}

			// UDP
			ipHelper.GetExUdpConnexions();
			for (int i = 0; i < ipHelper.UdpExConnexion.dwNumEntries; i++)
			{
				openPortRow = auditDS.GAS_OPEN_PORTS.NewGAS_OPEN_PORTSRow();
				openPortRow.PORT_NUMBER = decimal.Parse(ipHelper.UdpExConnexion.table[i].Local.Port.ToString());
				openPortRow.PORT_TYPE = "UDP";
				openPortRow.SERVICE = ipHelper.UdpExConnexion.table[i].ProcessName;
				openPortRow.HOST_AUDIT = hostAudit.ID;
				openPortRow.MORE_DETAILS = "FROM: " + ipHelper.UdpExConnexion.table[i].Local.Address.ToString() + ":" + ipHelper.UdpExConnexion.table[i].Local.Port.ToString();
				auditDS.GAS_OPEN_PORTS.AddGAS_OPEN_PORTSRow(openPortRow);
			}

			#endregion
			Console.WriteLine("After generating Open ports with IPHlpApi.dll");

			return auditDS;
		}
	}
}
